/***************************************************************************
* Copyright (C) 2003-2007 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
***************************************************************************/
package org.exoplatform.platform.gadget.services.LoginHistory;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.container.xml.ValueParam;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.access.PermissionType;
import org.exoplatform.services.jcr.core.ExtendedNode;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.jcr.impl.core.query.QueryImpl;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.organization.OrganizationService;
import org.picocontainer.Startable;
/**
* Created by The eXo Platform SARL Author : Tung Vu Minh tungvm@exoplatform.com
* Apr 21, 2011 6:19:21 PM
*/
public class LoginHistoryServiceImpl implements LoginHistoryService, Startable {
private static final Log LOG = ExoLogger.getLogger(LoginHistoryServiceImpl.class);
private static String HOME = "exo:LoginHistoryHome";
private static String LOGIN_HISTORY = "loginHistory";
private static String LOGIN_COUNTER = "loginCounter";
private static String BEFORE_LAST_LOGIN = "exo:LoginHisSvc_beforeLastLogin";
private static String LAST_LOGIN_TIME = "exo:LoginHisSvc_lastLogin";
private static int MAX_NUM_OF_LOGIN_HISTORY_ENTRIES = 0;
private static int DAYS_FOR_KEEPING_USER_STATISTIC = 0;
private static int DAYS_FOR_KEEPING_GLOBAL_STATISTIC = 0;
private static long DAY_IN_MILLISEC = 86400000;
private RepositoryService repositoryService;
/**
* Init LoginHistoryServiceImpl with RepositoryService from the container.
*
* @param repositoryService
*/
public LoginHistoryServiceImpl(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
}
@Override
public void start() {
// Create login history node
try {
createHomeNode();
} catch (RepositoryException e) {
LOG.error("Error of LoginHistoryServiceImpl start: " + e.getMessage(), e);
throw new RuntimeException(e);
}
}
@Override
public void stop() {
// do nothing
}
/**
* Create exo:LoginHistoryHome node.
*
* @throws RepositoryException
*/
protected void createHomeNode() throws RepositoryException {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
ManageableRepository currentRepo = this.repositoryService.getCurrentRepository();
Session session = sProvider.getSession(currentRepo.getConfiguration().getDefaultWorkspaceName(), currentRepo);
Node rootNode = session.getRootNode();
if (!rootNode.hasNode(HOME)) {
Node homeNode = rootNode.addNode(HOME, "exo:LoginHisSvc_loginHistoryService");
homeNode.addMixin("exo:privilegeable");
Map<String, String[]> permissions = new HashMap<String, String[]>();
permissions.put("*:/platform/administrators", PermissionType.ALL);
permissions.put("*:/platform/users", new String[]{PermissionType.READ});
((ExtendedNode)homeNode).setPermissions(permissions);
homeNode.addMixin("exo:owneable");
rootNode.save();
// --- PLF-2493 : Umbrella for usability issues
if (homeNode.canAddMixin("exo:hiddenable")) {
homeNode.addMixin("exo:hiddenable");
}
Node globalLoginCounterNode = homeNode.addNode(ALL_USERS, "exo:LoginHisSvc_globalLoginCounter");
globalLoginCounterNode.setProperty("exo:LoginHisSvc_globalLoginCounter_lastIndex", 0);
homeNode.save();
LOG.info("Login history storage initialized.");
}
} finally {
sProvider.close();
}
}
/**
* Apply configurations from service's xml
*/
public void addConfiguration(LoginHistoryPlugin plugin) {
InitParams initParams = plugin.getInitParams();
if (initParams != null) {
ValueParam MaxNumOfUserLoginHistoryEntries = initParams.getValueParam("MaxNumOfUserLoginHistoryEntries");
if (MaxNumOfUserLoginHistoryEntries != null)
MAX_NUM_OF_LOGIN_HISTORY_ENTRIES = Integer.parseInt(MaxNumOfUserLoginHistoryEntries.getValue());
ValueParam DaysForKeepingUserStatistic = initParams.getValueParam("DaysForKeepingUserStatistic");
if (DaysForKeepingUserStatistic != null)
DAYS_FOR_KEEPING_USER_STATISTIC = Integer.parseInt(DaysForKeepingUserStatistic.getValue());
ValueParam DaysForKeepingGlobalStatistic = initParams.getValueParam("DaysForKeepingGlobalStatistic");
if (DaysForKeepingGlobalStatistic != null)
DAYS_FOR_KEEPING_GLOBAL_STATISTIC = Integer.parseInt(DaysForKeepingGlobalStatistic.getValue());
}
}
/**
* Get user's last login time
*/
public long getLastLogin(String userId) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
Node homeNode = session.getRootNode().getNode(HOME);
return !homeNode.hasNode(userId) ? 0 : homeNode.getNode(userId).getProperty("exo:LoginHisSvc_lastLogin").getLong();
} catch (Exception e) {
LOG.debug("Error while retrieving " + userId + "'s last login: " + e.getMessage(), e);
throw e;
} finally {
sProvider.close();
}
}
/**
* Get last logins
*
* @param numItems
* @return List of {numItems} last login entries
* @throws Exception
*/
public List<LastLoginBean> getLastLogins(int numItems, String userIdFilter) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
QueryManager queryManager = session.getWorkspace().getQueryManager();
String sqlStatement = "SELECT * FROM exo:LoginHisSvc_userProfile " +
"WHERE (UPPER(exo:LoginHisSvc_userId) LIKE '%" + userIdFilter.toUpperCase() +
"%') OR (UPPER(exo:LoginHisSvc_userName) LIKE '%" + userIdFilter.toUpperCase() + "%') " +
"ORDER BY exo:LoginHisSvc_lastLogin DESC";
QueryImpl query = (QueryImpl) queryManager.createQuery(sqlStatement, Query.SQL);
query.setLimit(numItems);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
List<LastLoginBean> lastLogins = new ArrayList<LastLoginBean>();
Node node;
String userId, userName;
while (nodeIterator.hasNext()) {
node = nodeIterator.nextNode();
LastLoginBean lastLoginBean = new LastLoginBean();
userId = node.getName();
userName = node.getProperty("exo:LoginHisSvc_userName").getString();
lastLoginBean.setUserId(userId);
lastLoginBean.setUserName(userName.isEmpty() ? userId : userName);
lastLoginBean.setLastLogin(node.getProperty("exo:LoginHisSvc_lastLogin").getLong());
lastLoginBean.setBeforeLastLogin(node.getProperty("exo:LoginHisSvc_beforeLastLogin").getLong());
lastLogins.add(lastLoginBean);
}
return lastLogins;
} catch (Exception e) {
LOG.debug("Error while retrieving last logins: " + e.getMessage(), e);
throw e;
} finally {
sProvider.close();
}
}
/**
* Add an entry to user login history
*
* @param userId
* @param loginTime
* @throws Exception
*/
public void addLoginHistoryEntry(String userId, long loginTime) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
Node homeNode = session.getRootNode().getNode(HOME);
Node userNode, loginHistoryNode, loginCounterNode, globalLoginCounterNode;
String userName = getUserFullName(userId);
if (!homeNode.hasNode(userId)) {
userNode = homeNode.addNode(userId, "exo:LoginHisSvc_userProfile");
userNode.setProperty("exo:LoginHisSvc_userId", userId);
userNode.setProperty("exo:LoginHisSvc_userName", userName);
userNode.setProperty("exo:LoginHisSvc_lastLogin", 0);
userNode.setProperty("exo:LoginHisSvc_beforeLastLogin", 0);
homeNode.save();
loginHistoryNode = userNode.addNode(LOGIN_HISTORY, "exo:LoginHisSvc_loginHistory");
loginHistoryNode.setProperty("exo:LoginHisSvc_loginHistory_lastIndex", 0);
loginCounterNode = userNode.addNode(LOGIN_COUNTER, "exo:LoginHisSvc_loginCounter");
loginCounterNode.setProperty("exo:LoginHisSvc_loginCounter_lastIndex", 0);
userNode.save();
} else {
userNode = homeNode.getNode(userId);
}
userNode.setProperty("exo:LoginHisSvc_userName", userName);
userNode.setProperty("exo:LoginHisSvc_beforeLastLogin", userNode.getProperty("exo:LoginHisSvc_lastLogin").getLong());
userNode.setProperty("exo:LoginHisSvc_lastLogin", loginTime);
// Update login history
loginHistoryNode = userNode.getNode("loginHistory");
long loginHistory_lastIndex = loginHistoryNode.getProperty("exo:LoginHisSvc_loginHistory_lastIndex").getLong();
loginHistory_lastIndex++;
Node loginHistory_loginTimeNode = loginHistoryNode.addNode(Long.toString(loginHistory_lastIndex), "exo:LoginHisSvc_loginHistoryItem");
loginHistory_loginTimeNode.setProperty("exo:LoginHisSvc_loginHistoryItem_id", loginHistory_lastIndex);
loginHistory_loginTimeNode.setProperty("exo:LoginHisSvc_loginHistoryItem_userId", userId);
loginHistory_loginTimeNode.setProperty("exo:LoginHisSvc_loginHistoryItem_loginTime", loginTime);
// Keep only up to MAX_NUM_OF_LOGIN_HISTORY_ENTRIES last items
if (MAX_NUM_OF_LOGIN_HISTORY_ENTRIES > 0 && loginHistory_lastIndex > MAX_NUM_OF_LOGIN_HISTORY_ENTRIES) {
QueryManager queryManager = session.getWorkspace().getQueryManager();
String sqlStatement = "SELECT * FROM exo:LoginHisSvc_loginHistoryItem " +
"WHERE exo:LoginHisSvc_loginHistoryItem_userId = '" + userId + "' " +
"AND exo:LoginHisSvc_loginHistoryItem_id <= " + Long.toString(loginHistory_lastIndex - MAX_NUM_OF_LOGIN_HISTORY_ENTRIES);
QueryImpl query = (QueryImpl) queryManager.createQuery(sqlStatement, Query.SQL);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
while (nodeIterator.hasNext()) {
Node node = nodeIterator.nextNode();
node.remove();
}
}
loginHistoryNode.setProperty("exo:LoginHisSvc_loginHistory_lastIndex", loginHistory_lastIndex);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(loginTime);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
String loginDate = Long.toString(cal.getTimeInMillis());
// Update login counter
loginCounterNode = userNode.getNode("loginCounter");
long loginCounter_lastIndex = loginCounterNode.getProperty("exo:LoginHisSvc_loginCounter_lastIndex").getLong();
Node loginCounter_loginDateNode;
if (!loginCounterNode.hasNode(loginDate)) {
loginCounter_loginDateNode = loginCounterNode.addNode(loginDate, "exo:LoginHisSvc_loginCounterItem");
loginCounter_lastIndex++;
loginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_id", loginCounter_lastIndex);
loginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_userId", userId);
loginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_loginDate", Long.parseLong(loginDate));
loginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_loginCount", 1);
} else {
loginCounter_loginDateNode = loginCounterNode.getNode(loginDate);
long loginCount = loginCounter_loginDateNode.getProperty("exo:LoginHisSvc_loginCounterItem_loginCount").getLong();
loginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_loginCount", loginCount + 1);
}
// Keep only up to DAYS_FOR_KEEPING_USER_STATISTIC last items
if (DAYS_FOR_KEEPING_USER_STATISTIC > 0 && loginCounter_lastIndex > DAYS_FOR_KEEPING_USER_STATISTIC) {
QueryManager queryManager = session.getWorkspace().getQueryManager();
String sqlStatement = "SELECT * FROM exo:LoginHisSvc_loginCounterItem " +
"WHERE exo:LoginHisSvc_loginCounterItem_userId = '" + userId + "' " +
"AND exo:LoginHisSvc_loginCounterItem_id <= " + Long.toString(loginCounter_lastIndex - DAYS_FOR_KEEPING_USER_STATISTIC);
QueryImpl query = (QueryImpl) queryManager.createQuery(sqlStatement, Query.SQL);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
Node node;
while (nodeIterator.hasNext()) {
node = nodeIterator.nextNode();
node.remove();
}
}
loginCounterNode.setProperty("exo:LoginHisSvc_loginCounter_lastIndex", loginCounter_lastIndex);
// Update global login counter
globalLoginCounterNode = session.getRootNode().getNode(HOME).getNode(ALL_USERS);
long globalLoginCounter_lastIndex = globalLoginCounterNode.getProperty("exo:LoginHisSvc_globalLoginCounter_lastIndex").getLong();
Node globalLoginCounter_loginDateNode;
if (!globalLoginCounterNode.hasNode(loginDate)) {
globalLoginCounter_loginDateNode = globalLoginCounterNode.addNode(loginDate, "exo:LoginHisSvc_loginCounterItem");
globalLoginCounter_lastIndex++;
globalLoginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_id", globalLoginCounter_lastIndex);
globalLoginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_userId", ALL_USERS);
globalLoginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_loginDate", Long.parseLong(loginDate));
globalLoginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_loginCount", 1);
} else {
globalLoginCounter_loginDateNode = globalLoginCounterNode.getNode(loginDate);
long loginCount = globalLoginCounter_loginDateNode.getProperty("exo:LoginHisSvc_loginCounterItem_loginCount").getLong();
globalLoginCounter_loginDateNode.setProperty("exo:LoginHisSvc_loginCounterItem_loginCount", loginCount + 1);
}
// Keep only up to DAYS_FOR_KEEPING_GLOBAL_STATISTIC last items
if (DAYS_FOR_KEEPING_GLOBAL_STATISTIC > 0 && globalLoginCounter_lastIndex > DAYS_FOR_KEEPING_GLOBAL_STATISTIC) {
QueryManager queryManager = session.getWorkspace().getQueryManager();
String sqlStatement = "SELECT * FROM exo:LoginHisSvc_loginCounterItem " +
"WHERE exo:LoginHisSvc_loginCounterItem_userId = '" + ALL_USERS + "' " +
"AND exo:LoginHisSvc_loginCounterItem_id <= " + Long.toString(globalLoginCounter_lastIndex - DAYS_FOR_KEEPING_GLOBAL_STATISTIC);
QueryImpl query = (QueryImpl) queryManager.createQuery(sqlStatement, Query.SQL);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
Node node;
while (nodeIterator.hasNext()) {
node = nodeIterator.nextNode();
node.remove();
}
}
globalLoginCounterNode.setProperty("exo:LoginHisSvc_globalLoginCounter_lastIndex", globalLoginCounter_lastIndex);
userNode.save();
globalLoginCounterNode.save();
} catch (Exception e) {
LOG.debug("Error while adding login history entry for user '" + userId + "': " + e.getMessage(), e);
throw e;
} finally {
sProvider.close();
}
}
/**
* Get user login history
*
* @param userId
* @return List of login history entries in range [fromTime..toTime] of user {userId}
* @throws Exception
*/
public List<LoginHistoryBean> getLoginHistory(String userId, long fromTime, long toTime) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
QueryManager queryManager = session.getWorkspace().getQueryManager();
String sqlStatement = "SELECT * FROM exo:LoginHisSvc_loginHistoryItem " +
"WHERE " +
(userId.equals(LoginHistoryService.ALL_USERS) ? "" : "exo:LoginHisSvc_loginHistoryItem_userId = '" + userId + "' AND ") +
"(exo:LoginHisSvc_loginHistoryItem_loginTime BETWEEN " + Long.toString(fromTime) + " AND " + Long.toString(toTime) + ") " +
"ORDER BY exo:LoginHisSvc_loginHistoryItem_loginTime DESC";
QueryImpl query = (QueryImpl) queryManager.createQuery(sqlStatement, Query.SQL);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
List<LoginHistoryBean> list = new ArrayList<LoginHistoryBean>();
Node node;
String uId, uName;
while (nodeIterator.hasNext()) {
node = nodeIterator.nextNode();
LoginHistoryBean loginHistory = new LoginHistoryBean();
uId = node.getProperty("exo:LoginHisSvc_loginHistoryItem_userId").getString();
uName = getUserFullName(uId);
loginHistory.setUserId(uId);
loginHistory.setUserName(uName.isEmpty() ? uId : uName);
loginHistory.setLoginTime(node.getProperty("exo:LoginHisSvc_loginHistoryItem_loginTime").getLong());
list.add(loginHistory);
}
return list;
} catch (Exception e) {
LOG.debug("Error while getting login history of user '" + userId + "': " + e.getMessage(), e);
throw e;
} finally {
sProvider.close();
}
}
/**
* Get user's login count per days in range [fromDate..toDate]
*/
public List<LoginCounterBean> getLoginCountPerDaysInRange(String userId, long fromDate, long toDate) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
QueryManager queryManager = session.getWorkspace().getQueryManager();
String sqlStatement = "SELECT * FROM exo:LoginHisSvc_loginCounterItem " +
"WHERE exo:LoginHisSvc_loginCounterItem_userId = '" + userId + "' " +
"AND (exo:LoginHisSvc_loginCounterItem_loginDate BETWEEN " + Long.toString(fromDate) + " AND " + Long.toString(toDate) + ") " +
"ORDER BY exo:LoginHisSvc_loginCounterItem_loginDate ASC";
QueryImpl query = (QueryImpl) queryManager.createQuery(sqlStatement, Query.SQL);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
List<LoginCounterBean> list = new ArrayList<LoginCounterBean>();
Node node;
while (nodeIterator.hasNext()) {
node = nodeIterator.nextNode();
LoginCounterBean loginCountPerDay = new LoginCounterBean();
loginCountPerDay.setLoginDate(node.getProperty("exo:LoginHisSvc_loginCounterItem_loginDate").getLong());
loginCountPerDay.setLoginCount(node.getProperty("exo:LoginHisSvc_loginCounterItem_loginCount").getLong());
list.add(loginCountPerDay);
}
return list;
} catch (Exception e) {
LOG.debug("Error while getting login counts of user '" + userId + "': " + e.getMessage(), e);
throw e;
} finally {
sProvider.close();
}
}
/**
* Get user login count
*
* @return: The total number of logins since {fromDate} to {toDate} of user {userId}
*/
private int getLoginCount(String userId, long fromDate, long toDate) throws Exception {
List<LoginCounterBean> loginCounts = getLoginCountPerDaysInRange(userId, fromDate, toDate);
int sum = 0;
Iterator<LoginCounterBean> iter = loginCounts.iterator();
while (iter.hasNext()) {
sum += iter.next().getLoginCount();
}
return sum;
}
/**
* Get user login count per days in given week
*/
public List<LoginCounterBean> getLoginCountPerDaysInWeek(String userId, long week) throws Exception {
List<LoginCounterBean> list = new ArrayList<LoginCounterBean>();
List<Long> days = new ArrayList<Long>();
long now = System.currentTimeMillis();
long nextWeek = nextMonday(week);
long day = week;
LoginCounterBean loginCountPerDay;
do {
loginCountPerDay = new LoginCounterBean();
loginCountPerDay.setLoginDate(day);
loginCountPerDay.setLoginCount(day > now ? -1 : 0);
list.add(loginCountPerDay);
days.add(day);
day += DAY_IN_MILLISEC;
} while (day < nextWeek);
List<LoginCounterBean> counters = getLoginCountPerDaysInRange(userId, week, nextMonday(week) - DAY_IN_MILLISEC);
Iterator<LoginCounterBean> iter = counters.iterator();
while (iter.hasNext()) {
loginCountPerDay = iter.next();
list.set(days.indexOf(loginCountPerDay.getLoginDate()), loginCountPerDay);
}
return list;
}
/**
* Get user login count per weeks in given month
*/
public List<LoginCounterBean> getLoginCountPerWeeksInMonths(String userId, long fromMonth, int numOfMonths) throws Exception {
Calendar cal = Calendar.getInstance();
long now = cal.getTime().getTime();
cal.setTimeInMillis(fromMonth);
cal.add(Calendar.MONTH, numOfMonths);
long toMonth = cal.getTimeInMillis();
long fromDate, toDate = fromMonth;
List<LoginCounterBean> list = new ArrayList<LoginCounterBean>();
do {
fromDate = toDate;
toDate = nextMonday(toDate);
if (toDate > toMonth) toDate = toMonth;
LoginCounterBean loginCountPerWeek = new LoginCounterBean();
loginCountPerWeek.setLoginDate(fromDate);
loginCountPerWeek.setLoginCount(fromDate > now ? -1 : getLoginCount(userId, fromDate, toDate - DAY_IN_MILLISEC));
list.add(loginCountPerWeek);
} while (toDate < toMonth);
return list;
}
/**
* Get user login count per months in given year
*/
public List<LoginCounterBean> getLoginCountPerMonthsInYear(String userId, long year) throws Exception {
Calendar cal = Calendar.getInstance();
long now = cal.getTime().getTime();
cal.setTimeInMillis(year);
cal.add(Calendar.YEAR, 1);
long nextYear = cal.getTimeInMillis();
long fromDate, toDate = year;
List<LoginCounterBean> list = new ArrayList<LoginCounterBean>();
do {
fromDate = toDate;
cal.setTimeInMillis(toDate);
cal.add(Calendar.MONTH, 1);
toDate = cal.getTimeInMillis();
if (toDate > nextYear) toDate = nextYear;
LoginCounterBean loginCountPerWeek = new LoginCounterBean();
loginCountPerWeek.setLoginDate(fromDate);
loginCountPerWeek.setLoginCount(fromDate > now ? -1 : getLoginCount(userId, fromDate, toDate - DAY_IN_MILLISEC));
list.add(loginCountPerWeek);
} while (toDate < nextYear);
return list;
}
/**
* Utility function to get JCR session in current repository
*
* @param sessionProvider
* @return JCR session
* @throws Exception
*/
private Session getSession(SessionProvider sessionProvider) throws Exception {
ManageableRepository currentRepo = this.repositoryService.getCurrentRepository();
return sessionProvider.getSession(currentRepo.getConfiguration().getDefaultWorkspaceName(), currentRepo);
}
private static long nextMonday(long date) {
Calendar now = Calendar.getInstance();
now.setTimeInMillis(date);
int weekday = now.get(Calendar.DAY_OF_WEEK);
// calculate how much to add
// the 2 is the difference between Saturday and Monday
int days = weekday == Calendar.SUNDAY ? 1 : Calendar.SATURDAY - weekday + 2;
now.add(Calendar.DAY_OF_YEAR, days);
return now.getTimeInMillis();
}
private String getUserFullName(String userId) {
try {
OrganizationService service = (OrganizationService) ExoContainerContext.getCurrentContainer()
.getComponentInstanceOfType(OrganizationService.class);
return service.getUserHandler().findUserByName(userId).getFullName();
} catch (Exception e) {
return userId;
}
}
/**
* Get the list of all users who are logged after fromTime
*
* @param fromTime
* @return the list of user's name
*/
public Set<String> getLastUsersLogin(long fromTime) throws Exception {
Set<String> users = new LinkedHashSet<String>();
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
QueryManager queryManager = session.getWorkspace().getQueryManager();
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM exo:LoginHisSvc_userProfile WHERE")
.append(" exo:LoginHisSvc_lastLogin >= " + Long.toString(fromTime))
.append(" ORDER BY exo:LoginHisSvc_lastLogin DESC");
QueryImpl query = (QueryImpl) queryManager.createQuery(sb.toString(), Query.SQL);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
while (nodeIterator.hasNext()) {
Node node = nodeIterator.nextNode();
String userId = node.getProperty("exo:LoginHisSvc_userId").getString();
users.add(userId);
}
return users;
} catch (Exception e) {
LOG.debug("Error while getting login history of users " + e.getMessage(), e);
} finally {
sProvider.close();
}
return null;
}
/**
* An user is inactive if his last login is more than a number of days
*
* @param userId user's name
* @param days the number of days to verify if user is active or not
* @return
*/
public boolean isActiveUser(String userId, int days) {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
Node homeNode = session.getRootNode().getNode(HOME);
if (! homeNode.hasNode(userId)) {
return false;
}
Node userNode = homeNode.getNode(userId);
long beforeLastLogin = userNode.getProperty(BEFORE_LAST_LOGIN).getLong();
// return true if it's the first login of user
if (beforeLastLogin == 0) return true;
//
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - days);
long limitTime = cal.getTimeInMillis();
return beforeLastLogin >= limitTime;
} catch (Exception e) {
LOG.error("Error while get the last login of current user", e);
}
return false;
}
public Map<String, Integer> getActiveUsers(long fromTime) {
Map<String, Integer> users = new LinkedHashMap<String, Integer>();
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
QueryManager queryManager = session.getWorkspace().getQueryManager();
StringBuilder sb = new StringBuilder();
sb.append("SELECT * FROM exo:LoginHisSvc_userProfile WHERE")
.append(" exo:LoginHisSvc_lastLogin >= " + Long.toString(fromTime))
.append(" AND exo:LoginHisSvc_beforeLastLogin > 0")
.append(" ORDER BY exo:LoginHisSvc_lastLogin DESC");
QueryImpl query = (QueryImpl) queryManager.createQuery(sb.toString(), Query.SQL);
QueryResult result = query.execute();
NodeIterator nodeIterator = result.getNodes();
while (nodeIterator.hasNext()) {
Node node = nodeIterator.nextNode();
String userId = node.getProperty("exo:LoginHisSvc_userId").getString();
long numberOfLogin = node.getNode(LOGIN_HISTORY).getProperty("exo:LoginHisSvc_loginHistory_lastIndex").getLong();
users.put(userId, (int) numberOfLogin);
}
return users;
} catch (Exception e) {
LOG.debug("Error while getting login history of users " + e.getMessage(), e);
} finally {
sProvider.close();
}
return null;
}
public long getBeforeLastLogin(String userId) throws Exception {
SessionProvider sProvider = SessionProvider.createSystemProvider();
try {
Session session = this.getSession(sProvider);
Node homeNode = session.getRootNode().getNode(HOME);
return !homeNode.hasNode(userId) ? 0 : homeNode.getNode(userId).getProperty("exo:LoginHisSvc_beforeLastLogin").getLong();
} catch (Exception e) {
LOG.debug("Error while retrieving " + userId + "'s last login: " + e.getMessage(), e);
throw e;
} finally {
sProvider.close();
}
}
}